package net.fltx.p2p.client;

import de.felixroske.jfxsupport.FXMLController;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;
import net.fltx.p2p.common.P2PClientInfo;
import net.fltx.p2p.common.Packet;
import net.fltx.p2p.common.PacketType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.*;

@FXMLController
@Slf4j
public class MainFormController implements Initializable {

    private final Map<SocketChannel, FromP2PClient> p2pClientMap = new HashMap<>();
    private final Map<String, Packet> p2pMessageMap = new HashMap<>();

    @Autowired
    private SelfP2PClient selfP2PClient;

    @FXML
    private ListView<P2PClientInfo> listView;

    @FXML
    private ListView msgView;

    @FXML
    private TextArea textArea;

    @FXML
    public void onTextAreaKeyPressed(KeyEvent keyEvent) {
        if (keyEvent.isShiftDown() && keyEvent.getCode() == KeyCode.ENTER) {
            log.info(textArea.getText());
            SocketChannel fromServer = selfP2PClient.getP2pServer();
            Packet<Object> objectPacket = selfP2PClient.makePacket();
            objectPacket.setMessage(textArea.getText());
            objectPacket.setType(PacketType.CLIENT_MESSAGE);
            objectPacket.sendTo(fromServer);
        }

    }


    public void onUpdateList(List<P2PClientInfo> list) {
        for (P2PClientInfo item : listView.getItems()) {
            boolean inNews = false;
            for (P2PClientInfo p2PClientInfo : list) {
                if (item.getUuid().equals(p2PClientInfo.getUuid())) {
                    BeanUtils.copyProperties(p2PClientInfo, item);
                    inNews = true;
                    list.remove(p2PClientInfo);
                    break;
                }
            }
            if (!inNews) {
                listView.getItems().remove(item);
            }
        }
        listView.getItems().addAll(list);

    }

    public void onServerConnect(P2PClientInfo p2PClient) {

    }

    public void onServerMessage(Packet packet) {
        switch (packet.getType()) {
            case SERVER_LIST:
        }
    }

    public void onServerClose() {

    }


    public void onP2pClientConnect(SocketChannel channel) {
        if (!p2pClientMap.containsKey(channel)) {
            p2pClientMap.put(channel, new FromP2PClient(channel));
        }
    }

    public void onP2pClientMessage(SocketChannel channel, Packet packet) {

    }

    public void onP2pClientClose(SocketChannel channel) {
        try {
            channel.close();
        } catch (IOException ignore) {
        }
        FromP2PClient fromP2PClient = p2pClientMap.get(channel);
        log.info("已经断开: " + fromP2PClient);
        p2pClientMap.remove(channel);
    }

    public boolean sendMessage(SocketChannel channel, String msg) {
        byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
        Packet packet = new Packet();
        packet.setUsername(selfP2PClient.getUsername());
        packet.setUuid(selfP2PClient.getUuid());
        packet.setType(PacketType.CLIENT_MESSAGE);

        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        try {
            channel.write(buffer);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            try {
                channel.close();
            } catch (IOException ignore) {
            }
            FromP2PClient fromP2PClient = p2pClientMap.get(channel);
            log.info("已经断开: " + fromP2PClient);
            p2pClientMap.remove(channel);

            return false;
        }
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        listView.setCellFactory(new Callback<ListView<P2PClientInfo>, ListCell<P2PClientInfo>>() {
                                    @Override
                                    public ListCell<P2PClientInfo> call(ListView<P2PClientInfo> param) {
                                        return new P2PClientInfoCell();
                                    }
                                }
        );
        listView.getItems().add(selfP2PClient);
        try {
            selfP2PClient.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void onBtnRefreshAction(ActionEvent event) {
        log.info("刷新");
        selfP2PClient.start();
    }






}
